* retire some csv char based routines.
The last csv_lineparse user, garmin_txt, is converted to csv_linesplit.
xcsv_parse_val converted to use csv_stringtrim(QString,QString,int),
eliminating the other overloads.
xcsv_parse_style_line parsing of FIELD_DELIMITER, FIELD_ENCLOSER,
RECORD_DELIMITER and BADCHARS updated to use the above overload of
csv_stringtrim. FIELD_DELIMITER, FIELD_ENCLOSER and RECORD_DELIMITER
changed to trim, with a double quote enclosure, before character substitution.
There was a subtle bug in csvs_stringtrim(char, char, int). When trimming
a source that was all white space the first white space character would
be retained, while others would be trimmed. This did occur with CRNEWLINE,
but the bug allowed other substitutions to work, e.g. SPACE, NEWLINE, TAB, CR.
A small bug in csv_stringclean was fixed. If the to_nuke was empty an invalid
regular expression was created.
* save a few string conversions.
* and a few more conversions saved.
* review comments incorporated in garmin_txt reader.
* fix minor bug accumulating badchars.
csv_stringclean(const QString& source, const QString& to_nuke)
{
QString r = source;
- // avoid problematic regular rexpressions, e.g. xmapwpt generated [:\n:],
- // or one can imagine [0-9] when we meant the characters, '0', '-', and '9',
- // or one can imagine [^a] when we meant the characters '^' and 'a'.
- QRegularExpression regex = QRegularExpression(QString("[%1]").arg(QRegularExpression::escape(to_nuke)));
- assert(regex.isValid());
- return r.remove(regex);
-}
-
-// csv_stringtrim() - trim whitespace and leading and trailing
-// enclosures (quotes)
-// returns a copy of the modified string
-// usage: p = csv_stringtrim(string, "\"", 0)
-char*
-csv_stringtrim(const char* string, const char* enclosure, int strip_max)
-{
- static const char* p1 = nullptr;
- char* tmp = xstrdup(string);
- size_t elen;
-
- if (!strlen(string)) {
- return (tmp);
- }
-
- if (!enclosure) {
- elen = 0;
- } else {
- elen = strlen(enclosure);
- }
-
- char* p2 = tmp + strlen(tmp) - 1;
- p1 = tmp;
-
- /* trim off trailing whitespace */
- while ((p2 > p1) && isspace(*p2)) {
- p2--;
- }
-
- /* advance p1 past any leading whitespace */
- while ((p1 < p2) && (isspace(*p1))) {
- p1++;
- }
-
- /* if no maximum strippage, assign a reasonable value to max */
- strip_max = strip_max ? strip_max : 9999;
-
- /* if we have enclosures, skip past them in pairs */
- if (elen) {
- int stripped = 0;
- while (
- (stripped < strip_max) &&
- ((size_t)(p2 - p1 + 1) >= (elen * 2)) &&
- (strncmp(p1, enclosure, elen) == 0) &&
- (strncmp((p2 - elen + 1), enclosure, elen) == 0)) {
- p2 -= elen;
- p1 += elen;
- stripped++;
- }
- }
-
- /* copy what's left over back into tmp. */
- memmove(tmp, p1, (p2 - p1) + 1);
-
- tmp[(p2 - p1) + 1] = '\0';
-
- return (tmp);
-}
-
-// Is this really the replacement for the above? No.
-QString
-csv_stringtrim(const QString& source, const QString& enclosure)
-{
- QString r = source;
- r.replace(enclosure, "");
- return r.trimmed();
+ if (!to_nuke.isEmpty()) {
+ // avoid problematic regular rexpressions, e.g. xmapwpt generated [:\n:],
+ // or one can imagine [0-9] when we meant the characters, '0', '-', and '9',
+ // or one can imagine [^a] when we meant the characters '^' and 'a'.
+ QRegularExpression regex = QRegularExpression(QString("[%1]").arg(QRegularExpression::escape(to_nuke)));
+ assert(regex.isValid());
+ r.remove(regex);
+ }
+ return r;
}
// csv_stringtrim() - trim whitespace and leading and trailing
return retval;
}
-/*****************************************************************************/
-/* csv_lineparse() - extract data fields from a delimited string. designed */
-/* to handle quoted and delimited data within quotes. */
-/* returns temporary COPY of delimited data field (use it */
-/* or lose it on the next call). */
-/* usage: p = csv_lineparse(string, ",", "\"", line) [initial call] */
-/* p = csv_lineparse(NULL, ",", "\"", line) [subsequent calls] */
-/*****************************************************************************/
-char*
-csv_lineparse(const char* stringstart, const char* delimited_by,
- const char* enclosed_in, const int line_no)
-{
- static const char* p = nullptr;
- static char* tmp = nullptr;
- size_t dlen = 0, elen = 0, efound = 0;
- int enclosedepth = 0;
- short int hyper_whitespace_delimiter = 0;
-
- if (tmp) {
- xfree(tmp);
- tmp = nullptr;
- }
-
- if (strcmp(delimited_by, "\\w") == 0) {
- hyper_whitespace_delimiter = 1;
- }
-
- /*
- * This is tacky. Our "csv" format is actually "commaspace" format.
- * Changing that causes unwanted churn, but it also makes "real"
- * comma separated data (such as likely to be produced by Excel, etc.)
- * unreadable. So we silently change it here on a read and let the
- * whitespace eater consume the space.
- */
- if (strcmp(delimited_by, ", ") == 0) {
- delimited_by = ",";
- }
-
- if (!p) {
- /* first pass thru */
- p = stringstart;
-
- if (!p) {
- /* last pass out */
- return (nullptr);
- }
- }
-
- /* the beginning of the string we start with (this pass) */
- const char* sp = p;
-
- /* length of delimiters and enclosures */
- if ((delimited_by) && (!hyper_whitespace_delimiter)) {
- dlen = strlen(delimited_by);
- }
- if (enclosed_in) {
- elen = strlen(enclosed_in);
- }
- short int dfound = 0;
-
- while ((*p) && (!dfound)) {
- if ((elen) && (strncmp(p, enclosed_in, elen) == 0)) {
- efound = 1;
- p+=elen;
- if (enclosedepth) {
- enclosedepth--;
- } else {
- enclosedepth++;
- }
- continue;
- }
-
- if (!enclosedepth) {
- if ((dlen) && (strncmp(p, delimited_by, dlen) == 0)) {
- dfound = 1;
- } else if ((hyper_whitespace_delimiter) && (ISWHITESPACE(*p))) {
- dfound = 1;
- while (ISWHITESPACE(*p)) {
- p++;
- }
- } else {
- p++;
- }
- } else {
- p++;
- }
- }
-
- /* allocate enough space for this data field */
- tmp = (char*) xcalloc((p - sp) + 1, sizeof(char));
-
- strncpy(tmp, sp, (p - sp));
- tmp[p - sp] = '\0';
-
- if (elen && efound) {
- char* c = csv_stringtrim(tmp, enclosed_in, 0);
- xfree(tmp);
- tmp = c;
- }
-
- if (dfound) {
- /* skip over the delimited_by */
- p += dlen;
- } else {
- /* end of the line */
- p = nullptr;
- }
-
- if (enclosedepth != 0) {
- warning(MYNAME
- ": Warning- Unbalanced Field Enclosures (%s) on line %d\n",
- enclosed_in, line_no);
- }
- return (tmp);
-}
/*****************************************************************************/
/* csv_linesplit() - extract data fields from a delimited string. designed */
QString
csv_stringclean(const QString& source, const QString& to_nuke);
-char*
-csv_stringtrim(const char* string, const char* enclosure, int strip_max);
-QString
-csv_stringtrim(const QString& source, const QString& enclosure);
QString
csv_stringtrim(const QString& string, const QString& enclosure, int strip_max);
QString
enum class CsvQuoteMethod {historic, rfc4180};
-char*
-csv_lineparse(const char* stringstart, const char* delimited_by, const char* enclosed_in, int line_no);
QStringList
csv_linesplit(const QString& string, const QString& delimited_by,
const QString& enclosed_in, const int line_no, CsvQuoteMethod method = CsvQuoteMethod::historic);
#include <QChar> // for QChar, QChar::Other_Control
#include <QIODevice> // for QIODevice, QIODevice::ReadOnly, QIODevice::WriteOnly
#include <QString> // for QString, operator!=
+#include <QStringList> // for QStringList
#include <QTextStream> // for QTextStream
#include <QVector> // for QVector
#include <Qt> // for CaseInsensitive
#include <QtGlobal> // for qPrintable
-#include "csv_util.h" // for csv_lineparse
+#include "csv_util.h" // for csv_linesplit
+#include "formspec.h" // for FormatSpecificDataList
#include "garmin_fs.h" // for garmin_fs_t, garmin_fs_alloc, garmin_fs_convert_category, GMSD_SECTION_CATEGORIES
#include "garmin_tables.h" // for gt_display_modes_e, gt_find_desc_from_icon_number, gt_find_icon_number_from_desc, gt_get_mps_grid_longname, gt_lookup_datum_index, gt_lookup_grid_type, GDB, gt_get_icao_cc, gt_get_icao_country, gt_get_mps_datum_name, gt_waypt_class_names, GT_DISPLAY_MODE...
#include "inifile.h" // for inifile_readstr
/* macros */
#define IS_VALID_ALT(a) (((a) != unknown_alt) && ((a) < GARMIN_UNKNOWN_ALT))
-#define DUPSTR(a) (((a) != NULL) && ((a)[0] != 0)) ? ((a)) : NULL
static char* opt_datum = nullptr;
static char* opt_dist = nullptr;
/* data parsers */
-static int
-parse_date_and_time(char* str, time_t* value)
+static bool
+parse_date_and_time(const QString& str, time_t* value)
{
struct tm tm;
memset(&tm, 0, sizeof(tm));
- char* cin = lrtrim(str);
- if (*cin == '\0') {
- return 0;
+ QString tstr = str.trimmed();
+ if (tstr.isEmpty()) {
+ return false;
}
+ const QByteArray ba = tstr.toUtf8();
+ const char* cin = ba.constData();
char* cerr = strptime(cin, date_time_format, &tm);
if (cerr == nullptr) {
cerr = strptime(cin, "%m/%d/%Y %I:%M:%S %p", &tm);
- is_fatal(cerr == nullptr, MYNAME ": Invalid date or/and time \"%s\" at line %d!", cin, current_line);
+ is_fatal(cerr == nullptr, MYNAME ": Invalid date or/and time \"%s\" at line %d!", qPrintable(tstr), current_line);
}
// printf(MYNAME "_parse_date_and_time: %02d.%02d.%04d, %02d:%02d:%02d\n",
// tm.tm_mday, tm.tm_mon+1, tm.tm_year+1900, tm.tm_hour, tm.tm_min, tm.tm_sec);
*value = mklocaltime(&tm);
- return 1;
+ return true;
}
static uint16_t
-parse_categories(const char* str)
+parse_categories(const QString& str)
{
- char buff[256];
- uint16_t val;
uint16_t res = 0;
- char* cx;
-
- if (*str == '\0') {
- return 0;
- }
-
- strncpy(buff, str, sizeof(buff));
- char* cin = lrtrim(buff);
- if (*cin == '\0') {
- return 0;
- }
-
- strcat(cin, ",");
- while ((cx = strchr(cin, ','))) {
- *cx++ = '\0';
- cin = lrtrim(cin);
- if (*cin != '\0') {
- if (!garmin_fs_convert_category(cin, &val)) {
- warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", cin, current_line);
+ const QStringList catstrings = str.split(',');
+ for (const auto& catstring : catstrings) {
+ QString cin = catstring.trimmed();
+ if (!cin.isEmpty()) {
+ uint16_t val;
+ if (!garmin_fs_convert_category(CSTR(cin), &val)) {
+ warning(MYNAME ": Unable to convert category \"%s\" at line %d!\n", qPrintable(cin), current_line);
} else {
res = res | val;
}
}
- cin = cx;
}
return res;
}
-static int
-parse_temperature(const char* str, double* temperature)
+static bool
+parse_temperature(const QString& str, double* temperature)
{
double value;
unsigned char unit;
- if ((str == nullptr) || (*str == '\0')) {
- return 0;
+ if (str.isEmpty()) {
+ return false;
}
- if (sscanf(str, "%lf %c", &value, &unit) == 2) {
+ if (sscanf(CSTR(str), "%lf %c", &value, &unit) == 2) {
unit = toupper(unit);
switch (unit) {
case 'C':
default:
fatal(MYNAME ": Unknown temperature unit \"%c\" at line %d!\n", unit, current_line);
}
- return 1;
+ return true;
} else {
- fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", str, current_line);
+ fatal(MYNAME ": Invalid temperature \"%s\" at line %d!\n", qPrintable(str), current_line);
}
- return 0;
+ return false;
}
static void
-parse_header()
+parse_header(const QStringList& lineparts)
{
- char* str;
int column = -1;
free_header(unknown_header);
- while ((str = csv_lineparse(nullptr, "\t", "", column++))) {
+ for (const auto& str : lineparts) {
+ column++;
header_lines[unknown_header][column] = strupper(xstrdup(str));
header_ct[unknown_header]++;
if (header_ct[unknown_header] >= MAX_HEADER_FIELDS) {
}
}
-static int
-parse_display(const char* str, int* val)
+static bool
+parse_display(const QString& str, int* val)
{
- if ((str == nullptr) || (*str == '\0')) {
- return 0;
+ if (str.isEmpty()) {
+ return false;
}
for (gt_display_modes_e i = GT_DISPLAY_MODE_MIN; i <= GT_DISPLAY_MODE_MAX; ++i) {
if (case_ignore_strcmp(str, gt_display_mode_names[i]) == 0) {
*val = i;
- return 1;
+ return true;
}
}
- warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", str, current_line);
- return 0;
+ warning(MYNAME ": Unknown display mode \"%s\" at line %d.\n", qPrintable(str), current_line);
+ return false;
}
static void
}
static void
-parse_grid()
+parse_grid(const QStringList& lineparts)
{
- char* str = csv_lineparse(nullptr, "\t", "", 1);
-
- if (str != nullptr) {
- if (strstr(str, "dd.ddddd") != nullptr) {
- grid_index = grid_lat_lon_ddd;
- } else if (strstr(str, "mm.mmm") != nullptr) {
- grid_index = grid_lat_lon_dmm;
- } else if (strstr(str, "mm'ss.s") != nullptr) {
- grid_index = grid_lat_lon_dms;
- } else {
- grid_index = gt_lookup_grid_type(str, MYNAME);
- }
- } else {
+ if (lineparts.size() < 1) {
fatal(MYNAME ": Missing grid headline!\n");
}
+
+ const QByteArray ba = lineparts.at(0).toUtf8();
+ const char* str = ba.constData();
+ if (strstr(str, "dd.ddddd") != nullptr) {
+ grid_index = grid_lat_lon_ddd;
+ } else if (strstr(str, "mm.mmm") != nullptr) {
+ grid_index = grid_lat_lon_dmm;
+ } else if (strstr(str, "mm'ss.s") != nullptr) {
+ grid_index = grid_lat_lon_dms;
+ } else {
+ grid_index = gt_lookup_grid_type(str, MYNAME);
+ }
}
static void
-parse_datum()
+parse_datum(const QStringList& lineparts)
{
- char* str = csv_lineparse(nullptr, "\t", "", 1);
-
- if (str != nullptr) {
- datum_index = gt_lookup_datum_index(str, MYNAME);
- } else {
+ if (lineparts.size() < 1) {
fatal(MYNAME ": Missing GPS datum headline!\n");
}
+
+ const auto& str = lineparts.at(0);
+ datum_index = gt_lookup_datum_index(CSTR(str), MYNAME);
}
static void
-parse_waypoint()
+parse_waypoint(const QStringList& lineparts)
{
- char* str;
int column = -1;
bind_fields(waypt_header);
garmin_fs_t* gmsd = garmin_fs_alloc(-1);
wpt->fs.FsChainAdd(gmsd);
- while ((str = csv_lineparse(nullptr, "\t", "", column++))) {
+ for (const auto& str : lineparts) {
+ column++;
int i;
double d;
int field_no = header_fields[waypt_header][column];
switch (field_no) {
case 1:
- wpt->shortname = DUPSTR(str);
+ if (!str.isEmpty()) {
+ wpt->shortname = str;
+ }
break;
case 2:
- wpt->notes = DUPSTR(str);
+ if (!str.isEmpty()) {
+ wpt->notes = str;
+ }
break;
case 3:
for (i = 0; i <= gt_waypt_class_map_line; i++) {
}
static void
-parse_route_header()
+parse_route_header(const QStringList& lineparts)
{
- char* str;
int column = -1;
auto* rte = new route_head;
bind_fields(route_header);
- while ((str = csv_lineparse(nullptr, "\t", "", column++))) {
+ for (const auto& str : lineparts) {
+ column++;
int field_no = header_fields[route_header][column];
switch (field_no) {
case 1:
- rte->rte_name = DUPSTR(str);
+ if (!str.isEmpty()) {
+ rte->rte_name = str;
+ }
break;
case 5:
rte->rte_urls.AddUrlLink(UrlLink(str));
}
static void
-parse_track_header()
+parse_track_header(const QStringList& lineparts)
{
- char* str;
int column = -1;
bind_fields(track_header);
auto* trk = new route_head;
- while ((str = csv_lineparse(nullptr, "\t", "", column++))) {
+ for (const auto& str : lineparts) {
+ column++;
int field_no = header_fields[track_header][column];
switch (field_no) {
case 1:
- trk->rte_name = DUPSTR(str);
+ if (!str.isEmpty()) {
+ trk->rte_name = str;
+ }
break;
case 6:
trk->rte_urls.AddUrlLink(UrlLink(str));
}
static void
-parse_route_waypoint()
+parse_route_waypoint(const QStringList& lineparts)
{
- char* str;
int column = -1;
Waypoint* wpt = nullptr;
bind_fields(rtept_header);
- while ((str = csv_lineparse(nullptr, "\t", "", column++))) {
+ for (const auto& str : lineparts) {
+ column++;
int field_no = header_fields[rtept_header][column];
switch (field_no) {
case 1:
- is_fatal((*str == '\0'), MYNAME ": Route waypoint without name at line %d!\n", current_line);
+ is_fatal((str.isEmpty()), MYNAME ": Route waypoint without name at line %d!\n", current_line);
wpt = find_waypt_by_name(str);
- is_fatal((wpt == nullptr), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", str, current_line);
+ is_fatal((wpt == nullptr), MYNAME ": Route waypoint \"%s\" not in waypoint list (line %d)!\n", qPrintable(str), current_line);
wpt = new Waypoint(*wpt);
break;
}
}
static void
-parse_track_waypoint()
+parse_track_waypoint(const QStringList& lineparts)
{
- char* str;
int column = -1;
bind_fields(trkpt_header);
auto* wpt = new Waypoint;
- while ((str = csv_lineparse(nullptr, "\t", "", column++))) {
+ for (const auto& str : lineparts) {
+ column++;
double x;
- if (! *str) {
+ if (str.isEmpty()) {
continue;
}
}
break;
case 9:
- WAYPT_SET(wpt, course, atoi(str));
+ WAYPT_SET(wpt, course, atoi(CSTR(str)));
break;
}
}
continue;
}
- /* bail back to a (utf-8) char string, this format isn't worth the conversion work */
- QByteArray utf8str = buff.toUtf8();
- char* cin = csv_lineparse(utf8str.constData(), "\t", "", 0);
+ QStringList lineparts = csv_linesplit(buff, "\t", "", 0);
- if (cin == nullptr) {
+ if (lineparts.size() < 1) {
continue;
}
-
- if (case_ignore_strcmp(cin, "Header") == 0) {
- parse_header();
- } else if (case_ignore_strcmp(cin, "Grid") == 0) {
- parse_grid();
- } else if (case_ignore_strcmp(cin, "Datum") == 0) {
- parse_datum();
- } else if (case_ignore_strcmp(cin, "Waypoint") == 0) {
- parse_waypoint();
- } else if (case_ignore_strcmp(cin, "Route Waypoint") == 0) {
- parse_route_waypoint();
- } else if (case_ignore_strcmp(cin, "Trackpoint") == 0) {
- parse_track_waypoint();
- } else if (case_ignore_strcmp(cin, "Route") == 0) {
- parse_route_header();
- } else if (case_ignore_strcmp(cin, "Track") == 0) {
- parse_track_header();
- } else if (case_ignore_strcmp(cin, "Map") == 0) /* do nothing */ ;
+ auto linetype = lineparts.at(0);
+ lineparts.removeFirst();
+
+ if (case_ignore_strcmp(linetype, "Header") == 0) {
+ parse_header(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Grid") == 0) {
+ parse_grid(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Datum") == 0) {
+ parse_datum(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Waypoint") == 0) {
+ parse_waypoint(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Route Waypoint") == 0) {
+ parse_route_waypoint(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Trackpoint") == 0) {
+ parse_track_waypoint(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Route") == 0) {
+ parse_route_header(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Track") == 0) {
+ parse_track_header(lineparts);
+ } else if (case_ignore_strcmp(linetype, "Map") == 0) /* do nothing */ ;
else {
- fatal(MYNAME ": Unknown identifier (%s) at line %d!\n", cin, current_line);
+ fatal(MYNAME ": Unknown identifier (%s) at line %d!\n", qPrintable(linetype), current_line);
}
- /* flush pending data */
- while (csv_lineparse(nullptr, "\t", "", 0));
}
}
}
QDateTime
-XcsvFormat::yyyymmdd_to_time(const char* s)
+XcsvFormat::yyyymmdd_to_time(const QString& s)
{
QDate d = QDate::fromString(s, "yyyyMMdd");
#if (QT_VERSION < QT_VERSION_CHECK(5, 14, 0))
XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle::field_map& fmp,
xcsv_parse_data* parse_data, const int line_no)
{
- const char* enclosure = "";
+ QString enclosure = "";
geocache_data* gc_data = nullptr;
if (fmp.printfc.isNull()) {
/* IGNORE -- Calculated Sequence # For Output*/
break;
case XcsvStyle::XT_SHORTNAME:
- wpt->shortname = csv_stringtrim(s, enclosure);
+ wpt->shortname = csv_stringtrim(value, enclosure, 0);
break;
case XcsvStyle::XT_DESCRIPTION:
- wpt->description = csv_stringtrim(s, enclosure);
+ wpt->description = csv_stringtrim(value, enclosure, 0);
break;
case XcsvStyle::XT_NOTES:
- wpt->notes = csv_stringtrim(s, "");
+ wpt->notes = value.trimmed();
break;
case XcsvStyle::XT_URL:
if (!parse_data->link_) {
}
break;
case XcsvStyle::XT_YYYYMMDD_TIME:
- wpt->SetCreationTime(yyyymmdd_to_time(s));
+ wpt->SetCreationTime(yyyymmdd_to_time(value));
break;
case XcsvStyle::XT_GMT_TIME:
wpt->SetCreationTime(sscanftime(s, fmp.printfc.constData(), 1));
}
break;
case XcsvStyle::XT_GEOCACHE_LAST_FOUND:
- wpt->AllocGCData()->last_found = yyyymmdd_to_time(s);
+ wpt->AllocGCData()->last_found = yyyymmdd_to_time(value);
break;
/* GEOCACHING STUFF ***************************************************/
break;
case XcsvStyle::XT_GEOCACHE_TYPE:
/* Geocache Type */
- wpt->AllocGCData()->type = gs_mktype(s);
+ wpt->AllocGCData()->type = gs_mktype(value);
break;
case XcsvStyle::XT_GEOCACHE_CONTAINER:
- wpt->AllocGCData()->container = gs_mkcont(s);
+ wpt->AllocGCData()->container = gs_mkcont(value);
break;
case XcsvStyle::XT_GEOCACHE_HINT:
wpt->AllocGCData()->hint = value.trimmed();
break;
case XcsvStyle::XT_GEOCACHE_ISAVAILABLE:
gc_data = wpt->AllocGCData();
- if (case_ignore_strcmp(csv_stringtrim(s, ""), "False") == 0) {
+ if (case_ignore_strcmp(value.trimmed(), "False") == 0) {
gc_data->is_available = status_false;
- } else if (case_ignore_strcmp(csv_stringtrim(s, ""), "True") == 0) {
+ } else if (case_ignore_strcmp(value.trimmed(), "True") == 0) {
gc_data->is_available = status_true;
} else {
gc_data->is_available = status_unknown;
break;
case XcsvStyle::XT_GEOCACHE_ISARCHIVED:
gc_data = wpt->AllocGCData();
- if (case_ignore_strcmp(csv_stringtrim(s, ""), "False") == 0) {
+ if (case_ignore_strcmp(value.trimmed(), "False") == 0) {
gc_data->is_archived = status_false;
- } else if (case_ignore_strcmp(csv_stringtrim(s, ""), "True") == 0) {
+ } else if (case_ignore_strcmp(value.trimmed(), "True") == 0) {
gc_data->is_archived = status_true;
} else {
gc_data->is_archived = status_unknown;
case XcsvStyle::XT_GPS_FIX:
wpt->fix = (fix_type)(atoi(s)-(fix_type)1);
if (wpt->fix < fix_2d) {
- if (!case_ignore_strcmp(s, "none")) {
+ if (!case_ignore_strcmp(value, "none")) {
wpt->fix = fix_none;
- } else if (!case_ignore_strcmp(s, "dgps")) {
+ } else if (!case_ignore_strcmp(value, "dgps")) {
wpt->fix = fix_dgps;
- } else if (!case_ignore_strcmp(s, "pps")) {
+ } else if (!case_ignore_strcmp(value, "pps")) {
wpt->fix = fix_pps;
} else {
wpt->fix = fix_unknown;
break;
/* Tracks and routes *********************************************/
case XcsvStyle::XT_ROUTE_NAME:
- parse_data->rte_name = csv_stringtrim(s, enclosure);
+ parse_data->rte_name = csv_stringtrim(value, enclosure, 0);
break;
case XcsvStyle::XT_TRACK_NEW:
parse_data->new_track = atoi(s);
break;
case XcsvStyle::XT_TRACK_NAME:
- parse_data->trk_name = csv_stringtrim(s, enclosure);
+ parse_data->trk_name = csv_stringtrim(value, enclosure, 0);
break;
/* OTHER STUFF ***************************************************/
const QStringList tokens = tokenstr.split(',');
if (op == u"FIELD_DELIMITER") {
- auto cp = xcsv_get_char_from_constant_table(tokens[0]);
+ auto sp = csv_stringtrim(tokenstr, "\"", 1);
+ auto cp = xcsv_get_char_from_constant_table(sp);
style->field_delimiter = cp;
- char* p = csv_stringtrim(CSTR(style->field_delimiter), " ", 0);
/* field delimiters are always bad characters */
- if (0 == strcmp(p, "\\w")) {
- style->badchars = " \n\r";
+ if (cp == u"\\w") {
+ style->badchars += " \n\r";
} else {
- style->badchars += p;
+ style->badchars += cp;
}
- xfree(p);
} else if (op == u"FIELD_ENCLOSER") {
- auto cp = xcsv_get_char_from_constant_table(tokens[0]);
+ auto sp = csv_stringtrim(tokenstr, "\"", 1);
+ auto cp = xcsv_get_char_from_constant_table(sp);
style->field_encloser = cp;
- char* p = csv_stringtrim(CSTR(style->field_encloser), " ", 0);
- style->badchars += p;
- xfree(p);
+ style->badchars += cp;
} else if (op == u"RECORD_DELIMITER") {
- auto cp = xcsv_get_char_from_constant_table(tokens[0]);
+ auto sp = csv_stringtrim(tokenstr, "\"", 1);
+ auto cp = xcsv_get_char_from_constant_table(sp);
style->record_delimiter = cp;
// Record delimiters are always bad characters.
- auto* p = csv_stringtrim(CSTR(style->record_delimiter), " ", 0);
- style->badchars += p;
- xfree(p);
+ style->badchars += cp;
} else if (op == u"FORMAT_TYPE") {
if (tokens[0] == u"INTERNAL") {
style->whitespace_ok = tokens[0].toInt();
} else if (op == u"BADCHARS") {
- char* sp = csv_stringtrim(CSTR(tokenstr), "\"", 1);
- QString cp = xcsv_get_char_from_constant_table(sp);
+ auto sp = csv_stringtrim(tokenstr, "\"", 1);
+ auto cp = xcsv_get_char_from_constant_table(sp);
style->badchars += cp;
- xfree(sp);
} else if (op =="PROLOGUE") {
style->prologue.append(tokenstr);
/* Member Functions */
- static QDateTime yyyymmdd_to_time(const char* s);
+ static QDateTime yyyymmdd_to_time(const QString& s);
static time_t sscanftime(const char* s, const char* format, int gmt);
static time_t addhms(const char* s, const char* format);
static QString writetime(const char* format, time_t t, bool gmt);